home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file handles filling of the buffer and contains some additional utility routines.
- */
-
- #include "video.h"
- #include "proto.h"
- #include "util.h"
-
- /* Declarations of global variables used. */
-
- int bitOffset;
- int bufLength;
- unsigned int *bitBuffer;
-
-
- /*
- *--------------------------------------------------------------
- *
- * correct_underflow --
- *
- * Called when buffer does not have sufficient data to
- * satisfy request for bits.
- * Calls get_more_data, an application specific routine
- * required to fill the buffer with more data.
- *
- * Results:
- * None really.
- *
- * Side effects:
- * buf_length and buffer fields in curVidStream structure
- * may be changed.
- *
- *--------------------------------------------------------------
- */
-
- void correct_underflow(void)
- {
- int status;
-
- status = get_more_data(curVidStream->buf_start, curVidStream->max_buf_length, &bufLength, &bitBuffer);
-
- if (status < 0) {
- if (!quietFlag) {
- fprintf (stderr, "\n");
- perror("Unexpected read error.");
- }
- exit(1);
- }
- else if ((status == 0) && (bufLength < 1)) {
- if (!quietFlag) {
- fprintf(stderr, "\nImproper or missing sequence end code.\n");
- }
- #ifdef ANALYSIS
- PrintAllStats();
- #endif
- if (!quietFlag) {
- PrintTimeInfo();
- }
-
- if (loopFlag) longjmp(env, 1);
- DestroyVidStream(curVidStream);
- exit(0);
- }
-
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * get_ext_data --
- *
- * Assumes that bit stream is at begining of extension
- * data. Parses off extension data into dynamically
- * allocated space until start code is hit.
- *
- * Results:
- * Pointer to dynamically allocated memory containing
- * extension data.
- *
- * Side effects:
- * Bit stream irreversibly parsed.
- *
- * Niceness -10000 !!!!
- *
- *--------------------------------------------------------------
- */
-
- char *get_ext_data (void)
- {
- int size, marker;
- char *dataPtr;
- unsigned int data;
-
- /* Set initial ext data buffer size. */
-
- size = EXT_BUF_SIZE;
-
- /* Allocate ext data buffer. */
-
- dataPtr = (char *) malloc(size);
-
- /* Initialize marker to keep place in ext data buffer. */
-
- marker = 0;
-
- /* While next data is not start code... */
- while ((show_bitsn(24,data)) != 0x000001) { /* data re-usage could be applied ! */
-
- /* Put ext data into ext data buffer. Advance marker. */
-
- get_bits8( dataPtr[marker] );
- marker++;
-
- /* If end of ext data buffer reached, resize data buffer. */
-
- if (marker == size) {
- size += EXT_BUF_SIZE;
- dataPtr = (char *) realloc(dataPtr, size);
- }
- }
-
- /* Realloc data buffer to free any extra space. */
-
- dataPtr = (char *) realloc(dataPtr, marker);
-
- /* Return pointer to ext data buffer. */
-
- return dataPtr;
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * next_start_code --
- *
- * Parses off bitstream until start code reached. When done
- * next 4 bytes of bitstream will be start code. Bit offset
- * reset to 0.
- *
- * Results:
- * Status code.
- *
- * Side effects:
- * Bit stream irreversibly parsed.
- *
- *--------------------------------------------------------------
- */
-
- int next_start_code(void)
- {
- int state;
- int byteoff;
- unsigned int data;
-
- /* If no current stream, return error. */
-
- if (curVidStream == NULL) return NO_VID_STREAM;
-
- /* If insufficient buffer length, correct underflow. */
-
- if (bufLength < 2) {
- correct_underflow();
- }
-
- /* If bit offset not zero, reset and advance buffer pointer. */
-
- byteoff = bitOffset & 7;
-
- if (byteoff != 0) {
- flush_bits((8-byteoff));
- }
-
- /* Set state = 0. */
-
- state = 0;
-
- /* While buffer has data ... */
-
- while(bufLength > 0) {
-
- /* If insufficient data exists, correct underflow. */
-
- if (bufLength < 2) {
- correct_underflow();
- }
-
- /* If next byte is zero... */
-
- get_bits8(data);
-
- if (data == 0) {
- if (state < 2) state++; /* If state < 2, advance state. */
- }
- /* If next byte is one... */
- else if (data == 1) {
- if (state == 2) state++; /* If state == 2, advance state (i.e. start code found). */
- /* Otherwise, reset state to zero. */
- else state = 0;
- }
- /* Otherwise byte is neither 1 or 0, reset state to 0. */
- else {
- state = 0;
- }
- if (state == 3) { /* If state == 3 (i.e. start code found)... */
-
- /* Set buffer pointer back and reset length & bit offsets so
- next bytes will be beginning of start code.
- */
-
- bitOffset -= 24;
-
- #ifdef ANALYSIS
- bitCount -= 24;
- #endif
-
- if (bitOffset < 0) {
- bitOffset += 32;
- bufLength++;
- bitBuffer--;
- }
-
- /* Return success. */
-
- return OK;
- }
- }
-
- /* Return underflow error. */
-
- return UNDERFLOW;
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * get_extra_bit_info --
- *
- * Parses off extra bit info stream into dynamically
- * allocated memory. Extra bit info is indicated by
- * a flag bit set to 1, followed by 8 bits of data.
- * This continues until the flag bit is zero. Assumes
- * that bit stream set to first flag bit in extra
- * bit info stream.
- *
- * Results:
- * Pointer to dynamically allocated memory with extra
- * bit info in it. Flag bits are NOT included.
- *
- * Side effects:
- * Bit stream irreversibly parsed.
- *
- *--------------------------------------------------------------
- */
-
- char *get_extra_bit_info (void)
- {
- int size, marker;
- char *dataPtr;
- unsigned int data;
-
- /* Get first flag bit; if flag is false, return NULL pointer (i.e. no extra bit info). */
-
- if (!(get_bits1(data))) return NULL;
-
- /* Initialize size of extra bit info buffer and allocate. */
-
- size = EXT_BUF_SIZE;
- dataPtr = (char *) malloc(size);
-
- /* Reset marker to hold place in buffer. */
-
- marker = 0;
-
- /* While flag bit is true. */
-
- while (data) {
-
- /* Place in extra bit info buffer. */
-
- get_bits8( dataPtr[marker] );
- marker++;
-
- /* If buffer is full, reallocate. */
-
- if (marker == size) {
- size += EXT_BUF_SIZE;
- dataPtr = (char *) realloc(dataPtr, size);
- }
-
- /* Get next flag bit. */
- get_bits1(data);
- }
-
- /* Reallocate buffer to free extra space. */
-
- dataPtr = (char *) realloc(dataPtr, marker);
-
- /* Return pointer to extra bit info buffer. */
-
- return dataPtr;
- }
-